A wc_rules.indexer.Slicer
object is essentially a set defined as a boolean-valued dictionary. The keys may be literals or namedtuples.
A positive slicer (psl) defines a set by inclusion, i.e., it maps elements contained in the set to True
values (returns False
for all other values). To create a positive slicer, use Slicer()
or Slicer(default=False)
.
A negative slicer (nsl) defines a set by exclusion, i.e., it maps elements not contained in the set to False
values (returns True
for all other values). To create a negative slicer, use Slicer(default=True)
.
In [1]:
from wc_rules.indexer import Slicer
In [2]:
# A positive slicer
S = Slicer(default=False).add_keys(['a','b'])
In [3]:
# Checking for included elements
S['a']
Out[3]:
In [4]:
# Checking for excluded elements
S['c']
Out[4]:
In [5]:
# A negative slicer
S = Slicer(default=True).add_keys(['c'])
In [6]:
# Checking for included elements
S['a']
Out[6]:
In [7]:
# Checking for excluded elements
S['c']
Out[7]:
Slicers can be combined key-wise using Boolean operators ~
, &
and |
denoting NOT, AND and OR respectively.
Since a positive slicer denotes the elements included in a set, its inversion ~
is a negative slicer that denotes the elements excluded from the set, i.e., its complement.
In [8]:
# inverting a positive slicer
S = Slicer(default=False).add_keys(['a','b'])
T = ~S
T.default,T['a'],T['b'],T['c']
Out[8]:
Similarly, the inversion of a negative slicer is a positive slicer.
In [9]:
# inverting a negative slicer
S = Slicer(default=True).add_keys(['a','b'])
T = ~S
T.default,T['a'],T['b'],T['c']
Out[9]:
The Boolean AND returns True
for all values that both slicers return True
. When mixing positive and negative slicers using AND, deMorgan's laws are followed.
In [10]:
# psl(A) & psl(B) = psl(intersection(A,B))
A = Slicer().add_keys(['a','b'])
B = Slicer().add_keys(['b','c'])
C = A & B
C.default, C['a'],C['b'],C['c']
Out[10]:
In [11]:
# psl(A) & nsl(B) = psl(A - intersection(A,B))
A = Slicer().add_keys(['a','b'])
Bp = Slicer(default=True).add_keys(['b','c'])
C = A & Bp
C.default, C['a'],C['b'],C['c']
Out[11]:
In [12]:
# Similarly, nsl(A) & psl(B) = psl(B - intersection(A,B))
Ap = Slicer(default=True).add_keys(['a','b'])
B = Slicer().add_keys(['b','c'])
C = Ap & B
C.default, C['a'],C['b'],C['c']
Out[12]:
In [13]:
# nsl(A) & nsl(B) = nsl(union(A,B))
Ap = Slicer(default=True).add_keys(['a','b'])
Bp = Slicer(default=True).add_keys(['b','c'])
C = Ap & Bp
C.default, C['a'],C['b'],C['c']
Out[13]:
The Boolean OR returns True
for all values that either slicer returns True
. When mixing positive and negative slicers using OR, deMorgan's laws are followed.
In [14]:
# psl(A) | psl(B) = psl(union(A,B))
A = Slicer().add_keys(['a','b'])
B = Slicer().add_keys(['b','c'])
C = A | B
C.default, C['a'],C['b'],C['c']
Out[14]:
In [15]:
# psl(A) | nsl(B) = nsl(B - intersection(A,B))
A = Slicer().add_keys(['a','b'])
Bp = Slicer(default=True).add_keys(['b','c'])
C = A | Bp
C.default, C['a'],C['b'],C['c']
Out[15]:
In [16]:
# Similarly, nsl(A) | psl(B) = nsl(A - intersection(A,B))
Ap = Slicer(default=True).add_keys(['a','b'])
B = Slicer().add_keys(['b','c'])
C = Ap | B
C.default, C['a'],C['b'],C['c']
Out[16]:
In [17]:
# nsl(A) | nsl(B) = nsl(intersection(A,B))
Ap = Slicer(default=True).add_keys(['a','b'])
Bp = Slicer(default=True).add_keys(['b','c'])
C = Ap | Bp
C.default, C['a'],C['b'],C['c']
Out[17]: